package com.zmn.mcc.cas.staff.log.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.log.client.user.operation.AddUserOperationLogRequest;
import com.zmn.log.client.user.operation.UserOperationLogClient;
import com.zmn.log.client.user.operation.item.DeviceLogItem;
import com.zmn.log.client.user.operation.item.event.AccessEventLogItem;
import com.zmn.log.client.user.operation.item.user.StafferUserLogItem;
import com.zmn.mcc.cas.model.StaffLog;
import com.zmn.mcc.cas.staff.log.entity.StaffLogQuery;
import com.zmn.mcc.cas.staff.log.service.interfaces.StaffLogService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * @version v1.0
 * @since 2019/7/8 17:45
 **/
@Service
public class MongoStaffLogService implements StaffLogService {

    private final String COLLECTION_NAME = "staff_operate_log";

    /**
     * 描述: 员工操作日志mongo 标识
     */
    public final static String STAFF_OPERATE_LOG = "staff_operate_log";

    @Autowired
    private MongoTemplate mongoTemplate;

    @Resource
    private UserOperationLogClient userOperationLogClient;


    @Override
    public void save(StaffLog log) {

        StafferUserLogItem userLogItem = new StafferUserLogItem();
        userLogItem.setUserId(log.getStaffId() != null ? String.valueOf(log.getStaffId()) : null);
        userLogItem.setUserName(log.getStaffName());

        AccessEventLogItem eventLogItem = new AccessEventLogItem();
        eventLogItem.setSite(log.getApp());
        eventLogItem.setUri(log.getUri());
        eventLogItem.setRequest(log.getReq());
        eventLogItem.setResponse(log.getRes());

        DeviceLogItem deviceLogItem = new DeviceLogItem();
        deviceLogItem.setIp(log.getIp());
        if (StringUtils.isNotEmpty(log.getReq())) {
            JSONObject req = JSON.parseObject(log.getReq());
            deviceLogItem.setDeviceDetail(req.getString("User-Agent"));
        }

        AddUserOperationLogRequest<AccessEventLogItem> request = new AddUserOperationLogRequest<>();
        request.setClientName("zmn-mcc-dubbo");
        request.setUser(userLogItem);
        request.setEvent(eventLogItem);
        request.setDevice(deviceLogItem);

        userOperationLogClient.addAccessEventLog(request);
    }

    @Override
    public List<StaffLog> listPageByQuery(StaffLogQuery query) {
        Query queryMongo = new Query();

        if (Objects.nonNull(query.getStaffId())) {
            queryMongo.addCriteria(Criteria.where("staffId").is(query.getStaffId()));
        }
        if (StringUtils.isNotEmpty(query.getRealName())) {
            Pattern realName = Pattern.compile("^.*" + query.getRealName() + ".*$", Pattern.CASE_INSENSITIVE);
            queryMongo.addCriteria(Criteria.where("realName").is(realName));
        }
        if (NumberUtil.isPositiveInteger(query.getCompanyId())) {
            queryMongo.addCriteria(Criteria.where("companyId").is(query.getCompanyId()));
        }
        if (NumberUtil.isPositiveInteger(query.getPlat())) {
            queryMongo.addCriteria(Criteria.where("plat").is(query.getPlat()));
        }
        if (NumberUtil.isPositiveInteger(query.getDeptId())) {
            queryMongo.addCriteria(Criteria.where("deptId").is(query.getDeptId()));
        }
        if (StringUtils.isNotEmpty(query.getDeptName())) {
            Pattern deptName = Pattern.compile("^.*" + query.getDeptName() + ".*$", Pattern.CASE_INSENSITIVE);
            queryMongo.addCriteria(Criteria.where("deptName").is(deptName));
        }
        if (StringUtils.isNotEmpty(query.getUri())) {
            queryMongo.addCriteria(Criteria.where("uri").is(query.getUri()));
        }
        if (StringUtils.isNotEmpty(query.getApp())) {
            queryMongo.addCriteria(Criteria.where("app").is(query.getApp()));
        }
        if (StringUtils.isNotEmpty(query.getIp())) {
            queryMongo.addCriteria(Criteria.where("ip").is(query.getIp()));
        }
        if (Objects.nonNull(query.getStartTime()) && Objects.nonNull(query.getEndTime())) {
            queryMongo.addCriteria(Criteria.where("time").gte(query.getStartTime()).lte(query.getEndTime()));
        }
        if (Objects.nonNull(query.getStartTime()) && Objects.isNull(query.getEndTime())) {
            queryMongo.addCriteria(Criteria.where("time").gte(query.getStartTime()));
        }
        if (Objects.isNull(query.getStartTime()) && Objects.nonNull(query.getEndTime())) {
            queryMongo.addCriteria(Criteria.where("time").lte(query.getEndTime()));
        }
        queryMongo.skip((query.getPageNum() - 1) * query.getPageSize()).limit(query.getPageSize());

        long count = mongoTemplate.count(queryMongo, StaffLog.class, STAFF_OPERATE_LOG);

        query.setTotalCount((int) count);
        queryMongo.with(Sort.by(Sort.Direction.DESC, "time"));

        return mongoTemplate.find(queryMongo, StaffLog.class, STAFF_OPERATE_LOG);
    }


}
